package com.link.base.base.contract.service;

import com.fasterxml.jackson.databind.ObjectMapper;
import com.link.base.base.approval.model.Flow;
import com.link.base.base.approval.service.FlowService;
import com.link.base.base.contract.dao.mybatis.mapper.PriContraSignMapper;
import com.link.base.base.contract.model.ModContract;
import com.link.base.base.contract.model.PriContraSign;
import com.link.base.base.message.push.service.PushService;
import com.link.core.basic.dao.mapper.BasicMapper;
import com.link.core.basic.service.BasicServiceImpl;
import com.link.core.basic.service.ServiceException;
import com.link.core.util.DateUtil;
import com.link.core.util.PropertyUtil;
import com.link.core.util.StringUtils;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import java.util.Date;
import java.util.List;

/**
 * 价格合同签订计划
 *
 * @author 王昊
 * @date 2021-04-06 13:13:26
 */
@Service
public class PriContraSignServiceImpl extends BasicServiceImpl<PriContraSign> implements PriContraSignService {

    @Resource
    private PriContraSignMapper    priContraSignMapper;

    @Resource
    private FlowService flowService;

    @Resource
    private ModContractService modContractService;

    @Resource
    private PushService pushService;

    @Override
    public BasicMapper<PriContraSign> getBasicMapper() {
        return priContraSignMapper;
    }

    /**
     * 价格合同签订计划审批
     * @param entity
     * @throws Exception
     */
    @Override
    public void priContSignSubmit(PriContraSign entity) throws Exception {
        //根据entity查询
        PriContraSign priContraSign = priContraSignMapper.queryById(entity);
        //定义审批流
        String approvalType = "priContSignSubmit";

        ObjectMapper mapper = new ObjectMapper();
        String approvalDetail = mapper.writeValueAsString(priContraSign);
        //创建审批流
        flowService.createFlow(priContraSign.getId(), approvalType, null, priContraSign.getContractName(),priContraSign.getId(), approvalDetail);
        //提交审批后，审批状态为【审批中】
        priContraSign.setSubmitStatus("InApproval");
        priContraSignMapper.update(priContraSign);
    }

    /**
     * 审批拒绝与通过方法
     * @param flow
     * @param arg1
     * @throws Exception
     */
    @Override
    public void apprSubmit(Flow flow, String arg1, String arg2, String arg3, String arg4, String arg5) throws Exception {
        Long priContraSignId = flow.getFlowObjId();
        PriContraSign priContraSign = new PriContraSign();
        priContraSign.setId(priContraSignId);
        PriContraSign priContraSign1 = priContraSignMapper.queryById(priContraSign);
        priContraSign1.setSubmitStatus(arg1);
        priContraSignMapper.update(priContraSign1);
    }

    @Override
    public void beforUpsert(PriContraSign entity) throws Exception {
        //保存时校验是否存在【是否超期】为否的记录，存在则抛错“已存在未超期的签订计划，请勿重复制定！”
        PriContraSign querSign = new PriContraSign();
        querSign.setPriContraId(entity.getPriContraId());
        List<PriContraSign> priContraSigns = priContraSignMapper.queryAll(querSign);
        if (priContraSigns != null && !priContraSigns.isEmpty()) {
            for (PriContraSign priContraSign : priContraSigns) {
                //遍历查到的签订计划，只要有一条记录的【是否超期】为否且这条记录不是当前行记录 ，就抛错“已存在未超期的签订计划，请勿重复制定！”
                if ("N".equals(priContraSign.getIsOvertime()) && !entity.getId().equals(priContraSign.getId())) {
                    throw new ServiceException("IYUCONTRACT-010");
                }
            }
        }

        //保存时校验录入的【下次合同计划签订日期】是否在当前时间之前，是的话，就超期啦 【是否超期】赋值是，反之赋值否
        Date now = new Date();
//        DateUtil dateUtil = new DateUtil();
        //DATETIME_FORMATTER是利用日期工具包创建一个SimpleDateFormat对象，再去parse解析获取到的String类型的日期值
        if (entity.getNextSignDate() == null) {
            throw new ServiceException("获取下次合同计划签订日期出错，请重新录入！");
        }
        Date nextSignDate = DateUtil.DATETIME_FORMATTER.parse(entity.getNextSignDate());

        if (nextSignDate.before(now) && entity.getNextActSignDate() == null) {
            //直接用日期对象进行比较 如果计划日期早于现在且实际日期为空，就说明超期啦
            entity.setIsOvertime("Y");
        } else {
            entity.setIsOvertime("N");
        }
    }


    /**
     * 价格合同签订预警
     * @throws Exception
     */
    @Override
    public void priContraSignTask() throws Exception {
        //签订计划预警（只查询是否超期为否的记录）
        //有实际时间
        //   按时完成了 啥也不干
        //无实际时间
        //   比较预期时间与当前时间
        //      今天之前七天  还没做呢，提醒快点做 （这个会提醒7次）
        //      今天之后      超期了！！【是否超期】变是， 提醒超期，向上级告状 （因为变为是了，因此这个提醒只会提醒一次）

        PriContraSign querSign = new PriContraSign();
        querSign.setIsOvertime("N");
        //只查询未超期的记录
        querSign.setAttr4("queryNotOverTime");
        List<PriContraSign> priContraSigns = priContraSignMapper.queryAll(querSign);
        if (!priContraSigns.isEmpty()) {
            for (PriContraSign priContraSign : priContraSigns) {
                //没有实际完成时间
                if (StringUtils.isBlank(priContraSign.getNextActSignDate())) {
                    Date planNextSignDate = DateUtil.DATETIME_FORMATTER.parse(priContraSign.getNextSignDate());
                    Date planNextSignDate7 = new Date(planNextSignDate.getTime() - 7 * 24 * 60 * 60 * 1000);
                    Date now = new Date();
                    //获取合同头信息以便展示
                    ModContract queryContr = new ModContract();
                    queryContr.setId(priContraSign.getPriContraId());
                    ModContract modContract = modContractService.queryById(queryContr);
                    String acctName = modContract.getAcctName() == null ? "null" : modContract.getAcctName();
                    String contractName = modContract.getContractName() == null ? "null" : modContract.getContractName();
                    String message1 = "客户" + acctName + "的价格合同" + contractName + "计划与" + planNextSignDate.getDate() + "签订，请您及时跟进！";
                    //判断今天是否在预计开始日期前第七天 之后 且 在预计开始时间之前 ,提醒快点做 “客户xxxx的价格合同xxxx（合同名称）计划于几年几月几号签订，请您及时跟进”
                    if (now.after(planNextSignDate7) && now.before(planNextSignDate)) {
                        sendPushNotice(priContraSign.getId(),modContract.getId(),message1,priContraSign.getCreatedBy());
                    }
                    //超过预计开始日期了,超期啦！！【是否超期】变是， 提醒超期，向上级告状
                    //客户xxxx的价格合同xxxx（合同名称）已到达计划签订日期，请您重新制定该合同的签订计划。若不重新制定签订计划，将会影响您的绩效考核”。
                    //同时升级提醒至综合科科长“业务经理xxx的价格合同未在计划日期内完成，当前计划已超期”
                    if (now.after(planNextSignDate)) {
                        priContraSign.setIsOvertime("Y");
                        priContraSignMapper.update(priContraSign);
                        String creatName = priContraSign.getCreatName() == null ? "null" : priContraSign.getCreatName();
                        String message2me = "客户" + acctName + "的价格合同" + contractName + "已到达计划签订日期，请您重新制定该合同的签订计划。若不重新制定签订计划，将会影响您的绩效考核！";
                        String message2Head = "业务经理" + creatName + "的价格合同" + contractName + "未在计划日期内完成，当前计划已超期";
                        sendPushNotice(priContraSign.getId(),modContract.getId(),message2me,priContraSign.getCreatedBy());
                        //注意！！这里的ID目前给的是测试账号【综合鱼】的ID，后期上线再进行配置
                        Long zongHeKeId = Long.valueOf(PropertyUtil.getCommonProperty("zongHeKeId"));
                        sendPushNotice(priContraSign.getId(),modContract.getId(),message2Head,zongHeKeId);
                    }

                }
            }
        }
    }

    /**
     * 发送系统消息
     *
     * @author NingLanhao
     * @param businessId   预警对象数据的row_id，如消费者id、拜访id
     * @param alertId      头ID
     * @param message 预警消息
     * @param userId       发送对象
     * @return void
     * @date 2019-10-09 14:14
     */
    private void sendPushNotice(Long businessId, Long alertId, String message, Long userId) throws Exception {
        // 发送消息 预警的系统消息里objectId保存预警记录id
        pushService.sampleMessageForModule(message, userId, businessId, "priContraSignTask");
    }
}